home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 38
/
Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso
/
-seriously_amiga-
/
misc
/
felix
/
source
/
processcomm.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-25
|
14KB
|
502 lines
//*************************************************************************//
// Filename: ProcessComm.cpp
// Autor: Christian Taulien of Strange Intelligence
// Purpose: Implementation für die Behandlung und die Kommunikation
// der Prozesse
// Creation: 29. März 1998
//*************************************************************************//
#include "global.h"
#include "ProcessComm.h"
#include "WindowList.h"
#include <string.h>
#include <stdio.h>
#include <dos/dostags.h>
#include <exec/types.h>
#include <rexx/errors.h>
#include <rexx/rxslib.h>
#include <utility/tagitem.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/rexxsyslib_protos.h>
#include <clib/utility_protos.h>
#include <clib/gadtools_protos.h>
extern FLXWatchListC *glob_poWatches;
struct MsgPort *glob_poReciever = NULL;
struct MsgPort *glob_poStopper = NULL;
struct Process *glob_poWorker = NULL;
char *glob_sPortName = "GOLDED.1";
WindowListC *glob_poWindowList = NULL;
ULONG* SAVEDS SendRexxCommand(UBYTE *port, UBYTE *cmd, struct MsgPort *replyPort)
/*S*/
{
TRACE("Entry");
Forbid();
struct MsgPort *rexxport;
if (rexxport = FindPort(port))
{
struct RexxMsg *rexxMsg, *answer;
if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL))
{
if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd)))
{
static ULONG result;
rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
PutMsg(rexxport, &rexxMsg->rm_Node);
if (replyPort)
{
do
{
WaitPort(replyPort);
if (answer = (struct RexxMsg *)GetMsg(replyPort))
{
result = answer->rm_Result1;
} // if
} while (!answer);
} // if
Permit();
// TRACE("zurück vom msg verschicken.");
if (replyPort)
{
if (answer->rm_Result1 == RC_OK)
{
if (answer->rm_Result2)
{
DeleteArgstring((UBYTE *)answer->rm_Result2);
} // if
} // if
DeleteArgstring((UBYTE *)ARG0(answer));
DeleteRexxMsg(answer);
} // if
return &result;
} // if
} // if
} // if
Permit();
return NULL;
}
/*E*/
void DispatchMessage(struct Message *arg_poMessage, BOOL arg_bAsync)
/*S*/
{
TRACE("Entry");
// bis jetzt noch kein richtiger dispatcher
// solange wir was zum verschicken haben, schicken wir das einfach los
if (arg_poMessage && arg_poMessage->mn_Node.ln_Name)
{
// wenn kein Asyncronen-Command
if (arg_bAsync || Strnicmp("QUIT", arg_poMessage->mn_Node.ln_Name, 4)==0)
{
TRACE(arg_poMessage->mn_Node.ln_Name);
SendRexxCommand(glob_sPortName, arg_poMessage->mn_Node.ln_Name, NULL);
// TRACE("Asyncronen Befehl an Golded geschickt");
}
else
{
struct MsgPort *msgPort;
if (msgPort = CreateMsgPort())
{
TRACE(arg_poMessage->mn_Node.ln_Name);
SendRexxCommand(glob_sPortName, arg_poMessage->mn_Node.ln_Name, msgPort);
// TRACE("Befehl an Golded geschickt");
DeleteMsgPort(msgPort);
} // if
} // if
delete arg_poMessage->mn_Node.ln_Name;
delete arg_poMessage;
} // if
}
/*E*/
void sendMsgToGoldED(char *arg_sCommand, char *arg_sParameter, BOOL arg_bAsync)
/*S*/
{
TRACE("Entry");
if (!arg_sParameter)
{
arg_sParameter = "";
} // if
// allocate the mem for the command-string
char *sCommand = new char [strlen(arg_sCommand)+strlen(arg_sParameter)+2];
if (sCommand)
{
sprintf(sCommand, arg_sCommand, arg_sParameter);
struct Message *poMessage = new struct Message;
if (poMessage)
{
memset(poMessage, 0, sizeof(struct Message));
poMessage->mn_Length = sizeof(struct Message);
poMessage->mn_Node.ln_Name = sCommand;
// TRACE("msg weitergeleitet:");
// TRACE(sCommand);
DispatchMessage(poMessage, arg_bAsync);
}
else
{
delete sCommand;
} // if
} // if
// Delay(50);
}
/*E*/
void SAVEDS handleAPIRemoteCmdMsg(FelixMessage *arg_poFLXMsg)
/*S*/
{
TRACE("Entry");
if (!arg_poFLXMsg || !arg_poFLXMsg->m_poTagList || arg_poFLXMsg->m_ulType!=FelixMessage::FLXMSG_REMOTECMD)
{
return;
} // if
switch (GetTagData(FLXTAG_REMOTECOMMAND, FLXWINDOWCMD_UNDEFINED, arg_poFLXMsg->m_poTagList))
{
case FLXREMOTECMD_RELOADFILE:
// TRACE("Datei soll nachgeladen werden");
{ // dummy scope
char *sFileName = (char *)GetTagData(FLXTAG_FileName, 0, arg_poFLXMsg->m_poTagList);
if (sFileName)
{
sendMsgToGoldED("WINDOW QUIET USE=\"%s\"", sFileName, TRUE);
sendMsgToGoldED("OPEN AGAIN FORCE NAME \"%s\"", sFileName, TRUE);
sendMsgToGoldED("GOTO CHANGE","", TRUE);
} // if
}
break;
default:
// TRACE("Unbekannte remotecmd-msg");
break;
} // switch
}
/*E*/
void SAVEDS handleAPIWindowMsg(FelixMessage *arg_poFLXMsg)
/*S*/
{
TRACE("Entry");
if (!arg_poFLXMsg || !arg_poFLXMsg->m_poTagList || arg_poFLXMsg->m_ulType!=FelixMessage::FLXMSG_WINDOWLIST)
{
return;
} // if
switch (GetTagData(FLXTAG_WINDOWCOMMAND, FLXWINDOWCMD_UNDEFINED, arg_poFLXMsg->m_poTagList))
{
case FLXWINDOWCMD_OPEN:
// TRACE("Fenster soll geöffnet werden");
{ // dummy scope
struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
if (apiMsg)
{
// wenn es noch keine Fensterliste gibt
if (!glob_poWindowList)
{
// eine anlegen
glob_poWindowList = new WindowListC(glob_poWatches);
} // if
// wenn es jetze ein Fenster gibt
if (glob_poWindowList)
{
static BOOL bStartedOnce = FALSE;
BOOL bKeepPos = GetTagData(FLXTAG_KeepPos, FALSE, arg_poFLXMsg->m_poTagList);
// wenn noch nicht gestartet
if (!bStartedOnce || !bKeepPos)
{
ULONG ulX = GetTagData(FLXTAG_Left, -1, arg_poFLXMsg->m_poTagList);
ULONG ulY = GetTagData(FLXTAG_Top, -1, arg_poFLXMsg->m_poTagList);
glob_poWindowList->setWindowPosition(ulX, ulY, TRUE);
bStartedOnce = TRUE;
} // if
ULONG ulEntries = GetTagData(FLXTAG_Entries, 20, arg_poFLXMsg->m_poTagList);
glob_poWindowList->setMaxVisibleEntries(ulEntries);
glob_poWindowList->openWindowList(apiMsg);
glob_poWindowList->updateWindowList(apiMsg->api_Instance);
} // if
} // if
else
{
// TRACE("kein FLXTAG_APIMSG in der TagList");
} // if
} // dummy scope
break;
case FLXWINDOWCMD_TEXTMODIFY:
// TRACE("Text wurde verändert");
if (glob_poWindowList)
{
struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
glob_poWindowList->updateModifiedFlag(apiMsg->api_Instance);
} // if
break;
case FLXWINDOWCMD_CLOSE:
// TRACE("Fenster soll geschlossen werden");
if (glob_poWindowList)
{
delete glob_poWindowList;
glob_poWindowList = NULL;
}
break;
case FLXWINDOWCMD_UPDATE:
// TRACE("Fenster soll geupdatet werden");
if (glob_poWindowList)
{
struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
if (apiMsg)
{
glob_poWindowList->updateWindowList(apiMsg->api_Instance);
} // if
} // if
break;
case FLXWINDOWCMD_CREATED:
if (glob_poWindowList)
{
struct APIMessage *apiMsg = (struct APIMessage *) GetTagData(FLXTAG_APIMSG, 0, arg_poFLXMsg->m_poTagList);
glob_poWindowList->getWNameList()->findWName(apiMsg->api_Instance)->m_bModified = FALSE;
GT_RefreshWindow(glob_poWindowList->getWindow(),0);
glob_poWindowList->refreshDesign();
}
default:
// TRACE("Unbekannte windowlist-msg");
break;
}
}
/*E*/
BOOL SAVEDS handleAPIMessage(struct Message *arg_poMessage)
/*S*/
{
TRACE("Entry");
if (!arg_poMessage)
{
// TRACE("Falscher Parameter!");
return FALSE;
} // if
char *sName = arg_poMessage->mn_Node.ln_Name;
TRACE(sName);
if (sName)
{
// Ist es die ende-Msg?
if (0 == strcmp("ende", sName))
{
// TRACE("Ende-Message erkannt");
// wenn die WindowList noch offen ist
if (glob_poWindowList)
{
delete glob_poWindowList;
glob_poWindowList = NULL;
} // if
return TRUE;
}
// ist es eine message für die WindowList-verwaltung
else if (0 == strcmp("windowlist", sName))
{
// TRACE("WindowListMessage erhalten");
FelixMessage *poFLXMsg = (FelixMessage *) arg_poMessage;
handleAPIWindowMsg(poFLXMsg);
}
else if (0 == strcmp("remote", sName))
{
// TRACE("An ein befehl soll verschickt werden")
FelixMessage *poFLXMsg = (FelixMessage *) arg_poMessage;
handleAPIRemoteCmdMsg(poFLXMsg);
} // if
} // if
ReplyMsg(arg_poMessage);
return FALSE;
}
/*E*/
void BuildWaitMask(const struct MsgPort *arg_poMsgPort, ULONG &arg_rulMask)
/*S*/
{
// TRACE("Entry");
if (!arg_poMsgPort)
{
// TRACE("Kein Msg-Port");
return;
} // if
arg_rulMask |= (1L << (arg_poMsgPort->mp_SigBit));
}
/*E*/
void SAVEDS EntprellePort(struct MsgPort *arg_poPort)
/*S*/
{
TRACE("Entry");
if (!arg_poPort)
{
return;
}
struct Message *poMessage;
// solange wir messages kriegen
while (poMessage = GetMsg(arg_poPort))
{
// Wenn die Message einen ReplyPort hat
if (poMessage->mn_ReplyPort)
{
ReplyMsg(poMessage);
} // if
} // while
}
/*E*/
void SAVEDS FelixTask(void)
/*S*/
{
TRACE("Entry");
struct Message *poMessage = NULL;
if (glob_poReciever = CreateMsgPort())
{
// wenn der Empfänger-Port vorhanden ist
if (glob_poReciever)
{
BOOL done = FALSE;
while(!done)
{
// TRACE("Thread-msg-schleife");
ULONG ulSigMask = NULL;
BuildWaitMask(glob_poReciever, ulSigMask);
// wenn auch ein fenster existiert
if (glob_poWindowList && glob_poWindowList->getWindow())
{
BuildWaitMask(glob_poWindowList->getWindow()->UserPort, ulSigMask);
} // if
// TRACE("go waiting...");
Wait(ulSigMask);
// TRACE("waking up...");
while (!done && (poMessage = GetMsg(glob_poReciever)))
{
// TRACE("GetMsg()-schleife für api");
done = handleAPIMessage(poMessage);
// TRACE("zurück von handleapimsg()");
// ! diese Messages müssen nicht beantwortet werden !
} // while
if (!done && glob_poWindowList)
{
// TRACE("Versuche handleWindowList");
BOOL bClose = glob_poWindowList->handleWindowList();
if (bClose)
{
delete glob_poWindowList;
glob_poWindowList = NULL;
} // if
} // if
} // while
// Aufräumen
EntprellePort(glob_poReciever);
DeleteMsgPort(glob_poReciever);
glob_poReciever = NULL;
} // if
// Message jetzt zurückschicken
glob_poWorker = NULL;
// TRACE("Steige jetzt wieder aus");
if (poMessage)
{
PutMsg(glob_poStopper, poMessage);
}
else
{
// TRACE("exit ohne message!!!");
} // if
} // if
}
/*E*/
void SendeNachricht(char *arg_sName, UBYTE arg_uyMsgType, ULONG arg_eTags ...)
/*S*/
{
TRACE("Entry");
SendeNachrichtA(arg_sName, arg_uyMsgType, (struct TagItem *) &arg_eTags);
}
/*E*/
void SendeNachrichtA(char *arg_sName, UBYTE arg_uyMsgType, struct TagItem *arg_poTagList)
/*S*/
{
TRACE("Entry");
struct MsgPort *poPort;
// Wenn Stopper-Port vorhanden
if (poPort = CreateMsgPort())
{
// Wenn Reciever-Port vorhanden
if (glob_poReciever && glob_poWorker)
{
struct FelixMessage oMessage;
memset(&oMessage, 0, sizeof(struct FelixMessage));
oMessage.mn_Length = sizeof(struct FelixMessage);
oMessage.mn_Node.ln_Name = arg_sName;
oMessage.m_ulType = arg_uyMsgType;
oMessage.m_poTagList = arg_poTagList;
oMessage.mn_ReplyPort = poPort;
// TRACE("schicke Nachricht");
PutMsg(glob_poReciever, &oMessage);
// TRACE("Nachricht abgeschickt");
WaitPort(poPort);
// TRACE("Zurück von warte auf reply");
} // if
DeleteMsgPort(poPort);
} // if
}
/*E*/
void BeendeProzess(void)
/*S*/
{
TRACE("Entry");
// Wenn Stopper-Port vorhanden
if (glob_poStopper = CreateMsgPort())
{
// Wenn Reciever-Port vorhanden
if (glob_poReciever)
{
// Wenn der Prozess auch vorhanden
if (glob_poWorker)
{
struct Message oMessage;
memset(&oMessage, 0, sizeof(struct Message));
oMessage.mn_Length = sizeof(struct Message);
oMessage.mn_Node.ln_Name = "ende";
PutMsg(glob_poReciever, &oMessage);
// TRACE("Ende-Message abgeschickt");
WaitPort(glob_poStopper);
} // if
} // if
EntprellePort(glob_poStopper);
DeleteMsgPort(glob_poStopper);
glob_poStopper = NULL;
} // if
}
/*E*/
void StarteProzess(void)
/*S*/
{
TRACE("Entry");
glob_poWorker = CreateNewProcTags(NP_Entry, FelixTask,
NP_Priority, FindTask(NULL)->tc_Node.ln_Pri + 5,
NP_Name, "Felix-Task (GoldED-API)",
TAG_DONE);
}
/*E*/